package com.boot.security.server.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.boot.security.server.dao.SysSettingsDao;
import com.boot.security.server.model.FileInfo;
import com.boot.security.server.model.SysSettings;
import com.boot.security.server.utils.ExcelUtil;
import com.boot.security.server.utils.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.boot.security.server.annotation.LogAnnotation;
import com.boot.security.server.dao.UserDao;
import com.boot.security.server.dto.UserDto;
import com.boot.security.server.model.SysUser;
import com.boot.security.server.page.table.PageTableHandler;
import com.boot.security.server.page.table.PageTableHandler.CountHandler;
import com.boot.security.server.page.table.PageTableHandler.ListHandler;
import com.boot.security.server.page.table.PageTableRequest;
import com.boot.security.server.page.table.PageTableResponse;
import com.boot.security.server.service.UserService;
import com.boot.security.server.utils.UserUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;

/**
 * 用户相关接口
 *
 * @author 小威老师
 */
@Api(tags = "用户")

@RestController
@RequestMapping("/users")
public class UserController {

  private static final Logger log = LoggerFactory.getLogger("adminLogger");

  @Autowired
  private UserService userService;
  @Autowired
  private UserDao userDao;
  @Autowired
  private SysSettingsDao sysSettingsDao;

  @Value("${files.path}")
  private String filesPath;

  @LogAnnotation
  @PostMapping
  @ApiOperation(value = "保存用户")
  @PreAuthorize("hasAuthority('sys:user:add')")
  public SysUser saveUser(@RequestBody UserDto userDto) {
    SysUser u = userService.getUser(userDto.getUsername());
    if (u != null) {
      throw new IllegalArgumentException(userDto.getUsername() + "已存在");
    }

    return userService.saveUser(userDto);
  }

  @LogAnnotation
  @PutMapping
  @ApiOperation(value = "修改用户")
  @PreAuthorize("hasAuthority('sys:user:add')")
  public SysUser updateUser(@RequestBody UserDto userDto) {
    return userService.updateUser(userDto);
  }

  @LogAnnotation
  @PutMapping(params = "headImgUrl")
  @ApiOperation(value = "修改头像")
  public void updateHeadImgUrl(String headImgUrl) {
    SysUser user = UserUtil.getLoginUser();
    UserDto userDto = new UserDto();
    BeanUtils.copyProperties(user, userDto);
    userDto.setHeadImgUrl(headImgUrl);

    userService.updateUser(userDto);
    log.debug("{}修改了头像", user.getUsername());
  }

  @LogAnnotation
  @PutMapping("/{username}")
  @ApiOperation(value = "修改密码")
  @PreAuthorize("hasAuthority('sys:user:password')")
  public void changePassword(@PathVariable String username, String oldPassword, String newPassword) {
    userService.changePassword(username, oldPassword, newPassword);
  }

  @GetMapping
  @ApiOperation(value = "用户列表")
  @PreAuthorize("hasAuthority('sys:user:query')")
  public PageTableResponse listUsers(PageTableRequest request) {
    return new PageTableHandler(new CountHandler() {

      @Override
      public int count(PageTableRequest request) {
        return userDao.count(request.getParams());
      }
    }, new ListHandler() {

      @Override
      public List<SysUser> list(PageTableRequest request) {
        List<SysUser> list = userDao.list(request.getParams(), request.getOffset(), request.getLimit());
        return list;
      }
    }).handle(request);
  }

  @ApiOperation(value = "当前登录用户")
  @GetMapping("/current")
  public SysUser currentUser() {
    return UserUtil.getLoginUser();
  }

  @ApiOperation(value = "根据用户id获取用户")
  @GetMapping("/{id}")
  @PreAuthorize("hasAuthority('sys:user:query')")
  public SysUser user(@PathVariable Long id) {
    return userDao.getById(id);
  }

  @LogAnnotation
  @PostMapping("/import")
  @ApiOperation(value = "用户导入")
  @PreAuthorize("hasAuthority('sys:user:add')")
  public UserDto importUser(MultipartFile file) throws IOException {
    UserDto userDto = new UserDto();
    String fileOrigName = file.getOriginalFilename();
    if (!fileOrigName.contains(".")) {
      throw new IllegalArgumentException("缺少后缀名");
    }
    String md5 = FileUtil.fileMd5(file.getInputStream());
    String pathname = FileUtil.getPath() + md5 + fileOrigName.substring(fileOrigName.lastIndexOf("."));
    String fullPath = filesPath + pathname;
    FileUtil.saveFile(file, fullPath);
    List[] list = ExcelUtil.readExcel(new File(fullPath));
    if(list == null){
      throw new IllegalArgumentException("导入模板无数据");
    }
    for(int i=0; i<list[1].size(); i++){
      HashMap map = ((HashMap)list[1].get(i));
      SysUser u = userService.getUser(map.get("用户名").toString());
      if (u != null) {
        throw new IllegalArgumentException(map.get("用户名") + "已存在");
      }
      userDto.setUsername(map.get("用户名").toString());
      userDto.setNickname(map.get("昵称").toString());
      userDto.setSex("女".equals(map.get("性别").toString())?0:1);
      userDto.setPhone(map.get("手机号").toString());
      userDto.setEmail(map.get("邮箱").toString());
      SysSettings sysSettingsGet = this.sysSettingsDao.getByName("default_password");
      userDto.setPassword(sysSettingsGet.getSettingValue());
      userService.saveUser(userDto);
    }
    return userDto;
  }

  @LogAnnotation
  @PutMapping("/resetPwd/{username}")
  @ApiOperation(value = "重置密码")
  @PreAuthorize("hasAuthority('sys:user:add')")
  public void resetPassword(@PathVariable String username) {
    String defaultPwd =  sysSettingsDao.getByName("default_password").getSettingValue();
    userService.resetPassword(username, defaultPwd);
  }

  @LogAnnotation
  @GetMapping("/changeStatus/{username}")
  @ApiOperation(value = "禁用/启用用户")
//  @PreAuthorize("hasAuthority('sys:user:disable')")
  public void changeStatus(@PathVariable String username, @RequestParam Long status) {
    userService.changeStatus(username, status);
  }

}
